package org.yray.sip.server;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;


@Slf4j
public class SipServer implements Runnable{


    private SipServerHandler sipServerHandler;

    public SipServerHandler getSipServerHandler() {
        return sipServerHandler;
    }

    public SipServer(SipServerHandler sipServerHandler)
    {
        this.sipServerHandler = sipServerHandler;
    }


    @Override
    public void run() {
        Thread.currentThread().setName("SipServer");
        EventLoopGroup bossGroup=new NioEventLoopGroup();
        try{
            //通过NioDatagramChannel创建Channel，并设置Socket参数支持广播
            //UDP相对于TCP不需要在客户端和服务端建立实际的连接，因此不需要为连接（ChannelPipeline）设置handler
            Bootstrap b=new Bootstrap();
            b.group(bossGroup)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    // 设置读缓冲区为2K
                    .option(ChannelOption.SO_RCVBUF, 100 * 1024)
                    // 设置写缓冲区为2K
                    .option(ChannelOption.SO_SNDBUF, 100 * 1024)
                    .handler(new ChannelInitializer<NioDatagramChannel>() {
                        @Override
                        protected void initChannel(NioDatagramChannel ch) {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(sipServerHandler);
                        }
                    });
            String runIp= sipServerHandler.getServerContext().getRunIp();
            int runPort = sipServerHandler.getServerContext().getRunPort();
            ChannelFuture channelFuture=b.bind(runIp,runPort).sync();
            sipServerHandler.setChannel(channelFuture.channel());
            log.info("SipServer 启动成功 ip:[{}],port:[{}]",runIp,runPort);
            channelFuture.channel().closeFuture().sync();
        }catch (Exception e){
            log.error("SipServer 启动错误:{}", ExceptionUtils.getStackTrace(e));
        }finally{
            bossGroup.shutdownGracefully();
        }
    }

}
